/*
 * @Author: zh
 * @Date: 2024-07-03 15:08:03
 * @LastEditors: zh
 * @LastEditTime: 2024-11-18 15:31:59
 * @Description:
 */
class MyPromise {
  constructor(callback) {
    // 初始化状态pending
    this.state = "pending";
    // 初始化成功状态的值
    this.value = undefined;
    // 初始化失败状态的值
    this.reason = undefined;
    // 存储成功状态的回调函数数组
    this.onResolveCallbacks = [];
    // 存储失败状态的回调函数数组
    this.onRejectCallbacks = [];

    // 调用传入的回调函数
    const resolve = this.resolve.bind(this);
    const reject = this.reject.bind(this);

    try {
      // 调用传入的回调函数，并传入resolve和reject函数
      callback(resolve, reject);
      // console.log('resolve',this.onResolveCallbacks);
    } catch (err) {
      // 失败则调用reject函数
      reject(err);
    }
  }
  resolve = (value) => {
    if (this.state === "pending") {
      // 更新状态为resolve
      this.state = "resolved";
      // 存储成功状态的值
      this.value = value;
      // 执行所有成功状态的回调函数·
      // this.onResolveCallbacks.forEach(fn => fn());
      this.invokeCallbacks(this.onResolveCallbacks, value);
    }
  };

  // 定义reject方法
  reject = (reason) => {
    if (this.state === "pending") {
      // 更新状态为reject
      this.state = "rejected";
      // 存储失败状态的值
      this.reason = reason;
      // 执行所有失败状态的回调函数
      //   this.onRejectedCallbacks.forEach((fn) => fn());

      this.invokeCallbacks(this.onRejectCallbacks, reason);
    }
  };
  invokeCallbacks(callbacks, value) {
    // 创建一个微任务
    callbacks.forEach((callback) => {
      // 创建一个微任务
      setTimeout(() => {
        try {
          callback(value);
        } catch (error) {
          console.log("Error", error);
        }
      }, 0);
    });
    this.onRejectCallbacks = [];
    this.onResolveCallbacks = [];
  }
  then(onResolved, onRejected) {
    // 如果onResolved是函数，则直接使用，否则默认返回值不变的函数
    onResolved =
      typeof onResolved === "function" ? onResolved : (value) => value;
    // 如果onRejected是函数，则直接使用，否则默认抛出错误的函数
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (err) => {
            throw err;
          };
    // 创建一个新的promise对象
    return new MyPromise((resolve, reject) => {
      if (this.state === "resolved") {
        this.executeCallback(onResolved, resolve, reject);
      }
      if (this.state === "rejected") {
        this.executeCallback(onRejected, resolve, reject);
      }
      if (this.state === "pending") {
        this.onResolveCallbacks.push(() =>
          this.executeCallback(onResolved, resolve, reject)
        );
        this.onRejectCallbacks.push(() =>
          this.executeCallback(onRejected, resolve, reject)
        );
      } else {
        // 执行完所有回调函数，清空数组
        this.onResolveCallbacks = [];
        this.onRejectCallbacks = [];
      }
    });
  }
  executeCallback(callback, resolve, reject) {
    try {
      const result = callback(
        this.state === "resolved" ? this.value : this.reason
      );
      // 如果回调函数返回的是一个promise对象，则使用其结果作为新的promise对象判断一个对象是否为某个构造函数的实例。
      resolve(result instanceof MyPromise ? result.value : result);
    } catch (error) {
      reject(error);
    }
  }
  catch(onRejected) {
    // 等同于then(null, onRejected)
    return this.then(null, onRejected);
  }
  /**
   * 接收一个 Promise 实例的数组或具有 Iterator 接口的对象作为参数（迭代器对象）
   * 这个方法返回一个新的 promise 对象，
   * 遍历传入的参数，用Promise.resolve()将参数"包一层"，使其变成一个promise对象
   * 参数所有回调成功才是成功，返回值数组与参数顺序一致
   * 参数数组其中一个失败，则触发失败状态，第一个触发失败的 Promise 错误信息作为 Promise.all 的错误信息。
   * @param {Array} promises - 一个包含Promise对象的数组。 非静态方法
   *        每个Promise对象都代表一个异步操作的结果。
   * @returns {MyPromise} - 合并后的Promise对象
   *
   */
  all(promises) {
    return new MyPromise((resolve, reject) => {
      // 记录成功的个数
      let resolvedCount = 0;
      // 记录传入数组的长度
      const values = new Array(promises.length);
      for (let i = 0; i < promises.length; i++) {
        if (MyPromise.isPromise(promises[i])) {
          return reject(new TypeError("argument must be a promise"));
          break;
        }
        promises[i].then(
          (value) => {
            resolvedCount++;
            values[i] = value;
            // 如果所有promise都成功，则返回成功状态，resolve(values)结果数组
            if (resolvedCount === promises.length) {
              resolve(values);
            }
          },
          (reason) => {
            // 只要有一个Promise失败，就reject整个Promise.all的结果
            reject(reason);
          }
        );
      }
    });
  }

  // 添加 MyPromise.race 方法
  race(promises){
    return new MyPromise((resolve, reject) => {
        promises.forEach((promise) => {
            promise.then(resolve, reject);
        });
    });
  }

  /**
   * 判断是否为Promise对象
   * @param {*} value - 待判断的对象
   * @returns {boolean} - 是否为Promise对象
   */
  static isPromise(value) {
    return (
      value instanceof MyPromise ||
      (typeof value === "object" &&
        value !== null &&
        typeof value.then === "function")
    );
  }
}
const test1 = new MyPromise((resolve, reject) => {
  // resolve('成功')
  resolve(1);
  // reject(2)
});
console.log(test1);
// const test2 = new MyPromise()
// test2.all([1,2])
// console.log(test2);
// const test3 = Promise.all(["test1","test2"]) //原生的promise兼容了，非promise对象
// console.log(test3);
